package org.simplextensions.ui.settings;

import org.simplextensions.annotations.ExtensionPoint;
import org.simplextensions.annotations.lifecycle.Add;
import org.simplextensions.graph.Graph;
import org.simplextensions.graph.NodeAlreadyExistsException;
import org.simplextensions.registry.Extension;
import org.simplextensions.registry.ExtensionPointAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
 * 
 * 
 * @author Tomasz Krzyzak, <a
 *         href="mailto:tomasz.krzyzak@gmail.com">tomasz.krzyzak@gmail.com</a>
 * @since 24-05-2010 21:18:52
 */
@ExtensionPoint(id = SettingsExtensionPoint.ID, extensionClass = ISettingsEditor.class)
public class SettingsExtensionPoint extends ExtensionPointAdapter {

	private static final Logger log = LoggerFactory.getLogger(SettingsExtensionPoint.class);

	public static final String ID = "SettingsExtensionPoint";
	public static final String Param_Parent = "parent";

	private Graph editorsGraph = new Graph("SettingsGraph");

	private Collection<Extension> rootEditors = new LinkedList<Extension>();

    @Add
	public void addExtension(org.simplextensions.registry.Extension extension) {
		String dependency = extension.getPropertyValue(Param_Parent).getStringValue();
		if ("".equals(dependency)) {
			dependency = null;
		}
		try {
			editorsGraph.addNode(extension.getId(), dependency != null ? new String[] { dependency } : null, extension);
		} catch (NodeAlreadyExistsException e1) {
			log.error("Settings editor with given id already exissts.", e1);
		}
		if (dependency == null) {
			this.rootEditors.add(extension);
		}
	}

	private SettingsEditorMetaData createMetaData(SettingsEditorMetaData parent, Extension e) {
		SettingsEditorMetaData result = new SettingsEditorMetaData(parent, (ISettingsEditor<?>) e.getExecutable());
		for (Object o : editorsGraph.getIncomingNodes(e)) {
			createMetaData(result, (Extension) o);
		}
		return result;
	}

	public List<SettingsEditorMetaData> getSettingsEditors() {
		List<SettingsEditorMetaData> result = new LinkedList<SettingsEditorMetaData>();
		for (Extension e : rootEditors) {
			result.add(createMetaData(null, e));
		}
		return result;
	}

}
